package com.xxmw.transaction.service.app.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxmw.transaction.common.excep.service.TransactionException;
import com.xxmw.transaction.common.utils.AESUtil;
import com.xxmw.transaction.common.utils.Assert;
import com.xxmw.transaction.mapper.app.UserMapper;
import com.xxmw.transaction.model.app.User;
import com.xxmw.transaction.service.app.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

	@Override
	@Transactional
	public User saveUser(String username, String password, String ip) throws TransactionException {
		User user = new User();
		user.setUsername(username);
		user.setSalt(IdWorker.get32UUID());
		user.setIp(ip);
		user.setCreateTime(new Date());
		String encryptPwd = convert(password, user.getSalt());
		user.setPassword(encryptPwd);
		save(user);
		return user;
	}

	@Override
	public User login(String username, String password, String ip)throws TransactionException {
		QueryWrapper<User> query = new QueryWrapper<>();
		query.eq("username", username);
		User user = getOne(query);
		if(user == null) {
			throw new TransactionException("用户名不存在!");
		}
		String encryptPwd = convert(password, user.getSalt());
		if(!encryptPwd.equals(user.getPassword())) {
			throw new TransactionException("密码错误!");
		}
		user.setIp(ip);
		user.setLastLoginTime(new Date());
		saveOrUpdate(user);
		return user;
	}

	@Override
	public User getUser(String username) {
		QueryWrapper<User> query = new QueryWrapper<>();
		query.eq("username", username);
		return getOne(query);
	}

	@Override
	public void modifyPass(String username, String pass) {
		User user = getUser(username);

		if (null == user) {
			throw new TransactionException("该用户不存在");
		}

		String encryptPwd = convert(pass, user.getSalt());
		user.setPassword(encryptPwd);

		updateById(user);
	}

	@Override
	public void addVipTime(String username, Integer addTime) {
		User user = getUser(username);

		if (null == user) {
			throw new TransactionException("该用户不存在");
		}

		Date expirationDate = user.getVipExpirationDate();
		Date now = new Date();
		Date newExpirationDate = null;
		if (Assert.isNullOrEmpty(expirationDate) || expirationDate.before(now)) {
			// 没有开通过VIP 字段为空 或者已到期
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DATE, addTime);
			newExpirationDate = calendar.getTime();
		} else {
			// VIP未过期 增加VIP时间
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(expirationDate);
			calendar.add(Calendar.DATE, addTime);
			newExpirationDate = calendar.getTime();
		}

		// 保存user信息
		user.setVipExpirationDate(newExpirationDate);
		updateById(user);
	}

	@Override
	public boolean isVip(String username) {
		User user = getUser(username);
		if (user.getVipExpirationDate() != null && user.getVipExpirationDate().compareTo(new Date()) > 0 ) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	@Transactional
	public void testVip(String username) {
		User user = getUser(username);
		if (Assert.isNullOrEmpty(user) || User.TestVipStatus.RECEIVED.value().equals(user.getTestVipStatus()) ) {
			throw new TransactionException("您已领取过该福利！");
		}
		User targetUser = new User();
		targetUser.setId(user.getId());
		targetUser.setTestVipStatus(User.TestVipStatus.RECEIVED.value());
		updateById(targetUser);
		addVipTime(username, 7);
	}

	private String convert(String message, String salt) throws TransactionException{
		try {
			String decrypt = AESUtil.encrypt(message);
			return new Sha256Hash(decrypt, salt).toHex();
		} catch (Exception e) {
			log.error("密码解密异常！", e);
			throw new TransactionException("系统繁忙稍后重试!");
		}
	}

}
